package com.africanmoviesmobile.fragment;

import java.io.IOException;
import java.util.Hashtable;
import java.util.Vector;

import org.pixmob.httpclient.HttpClientException;

import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AbsListView;
import android.widget.AbsListView.OnScrollListener;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.TextView;

import com.actionbarsherlock.app.SherlockListFragment;
import com.africanmoviesmobile.R;
import com.africanmoviesmobile.ui.BaseActivity;
import com.africanmoviesmobile.ui.CelebDetailActivity;
import com.africanmoviesmobile.util.bitmap.ImageCache.ImageCacheParams;
import com.africanmoviesmobile.util.bitmap.ImageFetcher;
import com.africanmoviesmobile.webservice.AmmWebService;
import com.africanmoviesmobile.webservice.BasicAsyncCallback;
import com.africanmoviesmobile.webservice.WebServiceException;
import com.africanmoviesmobile.webservice.inf.Celeb;
import com.africanmoviesmobile.webservice.inf.WebserviceObject;

public class CelebListFragment extends SherlockListFragment implements OnScrollListener {
	
	private LayoutInflater mLayoutInflater;
	private ListView mListView;
	private LinearLayout mLoadingProgress;
	
    private ImageFetcher mThumbnailImageFetcher;
	
	AmmWebService mAmmWebService;
	
    private CelebListAdapter mCelebListAdapter;
    
    private boolean mLastItemVisible = false;
    private boolean mLoadingInProgress = false;
	private int mResultPage;
	private int mPageCount;
	
	 /**
     * Empty constructor as per the Fragment documentation
     */
    public CelebListFragment() {}
	
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		
		int thumbnailWidth = getResources().getDimensionPixelSize(R.dimen.thumbnail_width);
		int thumbnailHeight = getResources().getDimensionPixelSize(R.dimen.thumbnail_height);
        mThumbnailImageFetcher = new ImageFetcher(getSherlockActivity(), thumbnailWidth, thumbnailHeight);
        mThumbnailImageFetcher.setLoadingImage(R.drawable.empty_photo);
        mThumbnailImageFetcher.addImageCache(getSherlockActivity().getSupportFragmentManager(), 
        							new ImageCacheParams(getSherlockActivity(), BaseActivity.CACHE_DIR_THUMBNAIL));
	}
	
	@Override
	public void onActivityCreated(Bundle savedInstanceState) {
		super.onActivityCreated(savedInstanceState);
		
		mListView = getListView();
        mListView.setOnScrollListener(this);
        mListView.setDividerHeight(0);
        
        mLayoutInflater = (LayoutInflater) getSherlockActivity().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        mLoadingProgress = (LinearLayout) mLayoutInflater.inflate(R.layout.loading_progress_small, null);
    	
        mListView.addHeaderView(mLoadingProgress);
        
        // Set up our adapter
        mCelebListAdapter = new CelebListAdapter();
        setListAdapter(mCelebListAdapter);
        
        mResultPage = 1;
        
        mAmmWebService = AmmWebService.getInstance(getSherlockActivity());
        
        Hashtable<String, String> params = new Hashtable<String, String>();
		params.put("page", Integer.toString(mResultPage));

		mAmmWebService.getCelebs(params, new BasicAsyncCallback() {

			public void onComplete(final WebserviceObject[] result, final Object state) {

				getSherlockActivity().runOnUiThread(new Runnable(){public void run() { mListView.removeHeaderView(mLoadingProgress); }});
				
				Celeb[] celebs = (Celeb[]) result;

				if ((celebs != null)) {
					
					mPageCount = mAmmWebService.getResultPageCount();
												
					for (int i = 0; i < celebs.length; i++) {
						
						final Celeb celeb = (Celeb) (celebs[i]);
						
						getSherlockActivity().runOnUiThread(new Runnable(){public void run() { mCelebListAdapter.add(celeb); }});
						
					}
				} 
				
			}

			public void onHttpClientException(final HttpClientException e, final Object state) {
				Log.w("AMM HttpClientException:", e.getMessage());
			}
			
			public void onIOException(final IOException e, final Object state) {
				Log.w("AMM IOException:", e.getMessage());
			}

			public void onWebServiceException(final WebServiceException e, final Object state) {
				Log.w("AMM WebServiceException:", e.getMessage());
			}

		}, null);

		
	}
	
	@Override
    public void onResume() {
        super.onResume();
        mThumbnailImageFetcher.setExitTasksEarly(false);
        mCelebListAdapter.notifyDataSetChanged();
    }

    @Override
    public void onPause() {
        super.onPause();
        mThumbnailImageFetcher.setPauseWork(false);
        mThumbnailImageFetcher.setExitTasksEarly(true);
        mThumbnailImageFetcher.flushCache();
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        mThumbnailImageFetcher.closeCache();
    }
	
	@Override
	public void onListItemClick(ListView l, View v, int position, long id) {
		final Intent intent = new Intent(getSherlockActivity(), CelebDetailActivity.class);
		intent.putExtra(CelebDetailActivity.EXTRA_CELEB_ID, (int) id);
        startActivity(intent);
	}

	@Override
	public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
		mLastItemVisible = (totalItemCount > 0) && (firstVisibleItem + visibleItemCount >= totalItemCount - 1);
	}

	@Override
	public void onScrollStateChanged(AbsListView view, int scrollState) {
		/**
		 * Check that the scrolling has stopped, and that the last item is
		 * visible.
		 */
		if ((scrollState == OnScrollListener.SCROLL_STATE_IDLE) && mLastItemVisible) {

			//check if we still have more page left and we aren't loading any data
			if ((mResultPage < mPageCount) && (!mLoadingInProgress)) {
				mListView.addFooterView(mLoadingProgress);
				mResultPage++;
				loadMoreCeleb();
				mLastItemVisible = false;
				mLoadingInProgress = true;
			}
			
		}
		
		// Pause fetcher to ensure smoother scrolling when flinging
        if (scrollState == OnScrollListener.SCROLL_STATE_FLING) {
            mThumbnailImageFetcher.setPauseWork(true);
        } else {
            mThumbnailImageFetcher.setPauseWork(false);
        }
	}

	public void loadMoreCeleb() {

		 	Hashtable<String, String> params = new Hashtable<String, String>();
			params.put("page", Integer.toString(mResultPage));

			mAmmWebService.getCelebs(params, new BasicAsyncCallback() {

			public void onComplete(final WebserviceObject[] result, final Object state) {
				
				getSherlockActivity().runOnUiThread(new Runnable() {public void run() { mListView.removeFooterView(mLoadingProgress); }});
				
				mLoadingInProgress = false;
				
				Celeb[] celebs = (Celeb[]) result;
				
				if ((celebs != null)) {
												
					for (int i = 0; i < celebs.length; i++) {
						
						final Celeb celeb = (Celeb) (celebs[i]);
							
						getSherlockActivity().runOnUiThread(new Runnable() {public void run() { mCelebListAdapter.add(celeb); }});
						
					}							
				}
				
			}

			public void onHttpClientException(final HttpClientException e, final Object state) {
				mLoadingInProgress = false;
				getSherlockActivity().runOnUiThread(new Runnable() {public void run() { mListView.removeFooterView(mLoadingProgress); }});
				Log.w("AMM WebServiceException:", e.getMessage());
			}
			
			public void onIOException(final IOException e, final Object state) {
				mLoadingInProgress = false;
				getSherlockActivity().runOnUiThread(new Runnable() {public void run() { mListView.removeFooterView(mLoadingProgress); }});
				Log.w("AMM WebServiceException:", e.getMessage());
			}

			public void onWebServiceException(final WebServiceException e, final Object state) {
				mLoadingInProgress = false;
				getSherlockActivity().runOnUiThread(new Runnable() {public void run() { mListView.removeFooterView(mLoadingProgress); }});
				Log.w("AMM WebServiceException:", e.getMessage());
			}

		}, null);

	}
	
	public class CelebListAdapter extends BaseAdapter {

		private Vector<Celeb> mListElements = new Vector<Celeb>();
		
		private class ViewHolder {
			public TextView mCelebName;
    	    public ImageView mCelebPhoto;
    	}
		
        public CelebListAdapter() {
        }

        public int getCount() {
        	if (mListElements.isEmpty()) {
    			return 0;
    		} else {
    			return mListElements.size();
    		}
        }

        public Object getItem(int position) {
        	Celeb celeb = (Celeb) mListElements.elementAt(position);
        	return celeb;
        }

        public long getItemId(int position) {
            Celeb celeb = (Celeb) mListElements.elementAt(position);
    		return celeb.getId();
        }

        public View getView(int position, View convertView, ViewGroup parent) {

        	Celeb celeb = (Celeb) mListElements.elementAt(position);

        	ViewHolder holder;
        	        	
        	View celebRow = convertView;
        	
        	if(celebRow == null){
        		
            	celebRow = mLayoutInflater.inflate(R.layout.celeb_listview_row, parent, false);
            	
            	holder  = new ViewHolder();
        		holder.mCelebPhoto = (ImageView) celebRow.findViewById(R.id.celeb_photo);
        		holder.mCelebName = (TextView) celebRow.findViewById(R.id.celeb_name);
        		
        		celebRow.setTag(holder);
        	}else{
        		holder = (ViewHolder) celebRow.getTag();
        	}
        	
        	holder.mCelebName.setText(celeb.getName());
        	mThumbnailImageFetcher.loadImage(celeb.getDefaultPhoto(), holder.mCelebPhoto);
        	
        	return celebRow;
        }
        
        public void add(Celeb data) {
        	mListElements.addElement(data);
            notifyDataSetChanged();
        }
        
    }
	
}
